﻿using System;
using System.Collections.Generic;
using System.Text;

namespace SilverlightBrowserReflectorPlugin
{
    using Reflector;
    using Reflector.CodeModel;
    using System.Net;
    using System.IO;
    using System.Windows.Forms;
    using System.Text.RegularExpressions;

    internal class SilverlightPackage : IPackage
    {
        private IWindowManager windowManager;
        internal static IServiceProvider ServiceProvider;
        private ICommandBarButton button;
        private IWindow window;

        public void Load(IServiceProvider sp)
        {
            ServiceProvider = sp;

            this.windowManager = (IWindowManager)ServiceProvider.GetService(typeof(IWindowManager));

           
            //page.Controls.Add(this.windowManager.Content);

            Viewer view = new Viewer();

            window = this.windowManager.Windows.Add("Silverlight Browser", view, "Silverlight Browser");
           
            

            ICommandBarManager cmb = (ICommandBarManager)ServiceProvider.GetService(typeof(ICommandBarManager));

            SilverlightCommandBarItem item = new SilverlightCommandBarItem();

            item.Click += new EventHandler(SilverlightCommandBarItem_Click);

            this.button = cmb.CommandBars["File"].Items.InsertButton(2, "Open &Silverlight URL", new EventHandler(this.SilverlightCommandBarItem_Click), Keys.U | Keys.Control);

        }


        void SilverlightCommandBarItem_Click(object sender, EventArgs e)
        {

            try
            {
                window.Visible = true;

                URLDialog urlDiag = new URLDialog();


                //if (DialogResult.OK == urlDiag.ShowDialog())
                {
                   
                }

            }
            catch (Exception ex)
            {
                Message = "JavaScript Silverlight Page Loaded";
            }
        }

        static string message;

        public static string Message
        {
            get { return SilverlightPackage.message; }
            set { SilverlightPackage.message = value; }
        }

        internal static Dictionary<string, string> Sniff(Uri uri, List<string> jsFiles, List<string> xamlFiles)
        {
            Message = string.Empty;

            Dictionary<string, string> files = new Dictionary<string, string>();
            try
            {
                if (jsFiles.Count == 0)
                {
                    Message = "Couldn't locate .js files";
                }

                string url = uri.ToString();
                string fileAndQuery = Path.GetFileName(uri.AbsolutePath) + uri.Query;
                Uri baseUrl = new Uri(url.Substring(0, url.Length - fileAndQuery.Length));

                foreach (string jsFile in jsFiles)
                {
                    string jsUrl = new Uri(baseUrl, jsFile).AbsoluteUri;
                    string jsContent = DownloadStringWithReader(jsUrl);
                    files.Add(jsFile, jsContent);
                }

                WebClient webClient = new WebClient();
                foreach (string xamlFile in xamlFiles)
                {
                    string xamlUrl = new Uri(baseUrl, xamlFile).AbsoluteUri;
                    string xamlContent = DownloadStringWithReader(xamlUrl);
                    files.Add(xamlFile, xamlContent);

                    // Then Find: assembly=ClientBin/SilverlightEventHandling.dll
                    string assemblyName = FindAssembly(xamlContent);
                    if (assemblyName == null)
                    {
                        // TODO: Show 'Source' if XAML contains something like the following:
                        //       <x:Code Source="DLRConsole.py" Type="text/python" />

                        Message = "JavaScript Silverlight Page Loaded";
                        continue;
                    }

                    string folderPath = Environment.GetFolderPath(Environment.SpecialFolder.ApplicationData) + "\\" + "Silverlight Reflector" + "\\";
                    if (!Directory.Exists(folderPath))
                    {
                        Directory.CreateDirectory(folderPath);
                    }

                    string assemblyUrl = new Uri(baseUrl, assemblyName).AbsoluteUri;
                    string assemblyFile = folderPath + Path.GetFileName(assemblyName);
                    webClient.DownloadFile(assemblyUrl, assemblyFile);

                    IAssemblyManager manager = (IAssemblyManager)ServiceProvider.GetService(typeof(IAssemblyManager));
                    ReplaceAssembly(manager, assemblyFile);
                }

                /*
                assemblyList.Add(asm.LoadFile(folderPath + assemblyName));
                */
            }
            catch (Exception ex)
            {
                Message = "JavaScript Silverlight Page Loaded";
            }

            return files;
        }

        private static void ReplaceAssembly(IAssemblyManager asm, string assemblyFile)
        {
            string assemblyName = Path.GetFileNameWithoutExtension(assemblyFile);
            foreach (IAssembly assembly in asm.Assemblies)
            {
                if (assembly.Name == assemblyName)
                {
                    asm.Unload(assembly);
                    break;
                }
            }

            asm.LoadFile(assemblyFile);
        }

        /*
        internal static List<IAssembly> assemblyList;
        */

        // Use StreamReader to avoid corruption at beginning of string.
        private static string DownloadStringWithReader(string url)
        {
            WebRequest request = HttpWebRequest.Create(new Uri(url));
            WebResponse response = request.GetResponse();
            Stream responseStream = response.GetResponseStream();
            StreamReader reader = new StreamReader(responseStream);
            return reader.ReadToEnd();
        }

        private static string FindAssembly(string xamlContent)
        {
            Regex reg = new Regex(@"assembly\s*=\s*(.+\.dll)");

            Match match = reg.Match(xamlContent);

            if (match.Success)
            {
                return match.Groups[1].Value;
            }

            return null;
        }

        public void Unload()
        {

        }

    }
}